/*******************************************************************************************
This file is part of iToday.

iToday is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

iToday is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with iToday.  If not, see <http://www.gnu.org/licenses/>.
* ------------------------------------------------------------------------------
*    File.h - raw unbuffered disk file I/O
* ------------------------------------------------------------------------------
*    Revision History
*    Date                  Author         Activity ID               Activity Headline
*    2010-03-19            CubeWang				none						initial 
*******************************************************************************************/

#include <altcecrt.h>
#include <atlcore.h>
#include <atlstr.h>
#include <atltime.h>
#include <strsafe.h>

#define DLL_EXPORT

#if defined DLL_EXPORT
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR __declspec(dllimport)
#endif

/////////////////////////////////////////////////////////////////////////////
// File status
struct CFileStatus
{
	CTime m_ctime;          // creation date/time of file
	CTime m_mtime;          // last modification date/time of file
	CTime m_atime;          // last access date/time of file
	ULONGLONG m_size;            // logical size of file in bytes
	BYTE m_attribute;       // logical OR of CFile::Attribute enum values
	BYTE _m_padding;        // pad the structure to a WORD
	TCHAR m_szFullName[_MAX_PATH]; // absolute path name
};

/*DECLDIR*/ class CFile
{
public:
	// Flag values
	enum OpenFlags {
		modeRead =         (int) 0x00000,
		modeWrite =        (int) 0x00001,
		modeReadWrite =    (int) 0x00002,
		shareCompat =      (int) 0x00000,
		shareExclusive =   (int) 0x00010,
		shareDenyWrite =   (int) 0x00020,
		shareDenyRead =    (int) 0x00030,
		shareDenyNone =    (int) 0x00040,
		modeNoInherit =    (int) 0x00080,
		modeCreate =       (int) 0x01000,
		modeNoTruncate =   (int) 0x02000,
		typeText =         (int) 0x04000, // typeText and typeBinary are
		typeBinary =       (int) 0x08000, // used in derived classes only
		osNoBuffer =       (int) 0x10000,
		osWriteThrough =   (int) 0x20000,
		osRandomAccess =   (int) 0x40000,
		osSequentialScan = (int) 0x80000,
	};

	enum Attribute {
		normal =    0x00,
		readOnly =  0x01,
		hidden =    0x02,
		system =    0x04,
		volume =    0x08,
		directory = 0x10,
		archive =   0x20
	};

	enum SeekPosition { begin = 0x0, current = 0x1, end = 0x2 };

	// Constructors
	DECLDIR CFile();
	DECLDIR CFile(HANDLE hFile);
	DECLDIR CFile(LPCTSTR lpszFileName, UINT nOpenFlags);

	// Attributes
	HANDLE m_hFile;

	DECLDIR ULONGLONG GetPosition() const;
	DECLDIR BOOL GetStatus(CFileStatus& rStatus) const;
	DECLDIR CString GetFileName() const;
	DECLDIR CString GetFilePath() const;
	DECLDIR void SetFilePath(LPCTSTR lpszNewName);

	// Operations
	DECLDIR BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags);

	DECLDIR static void Rename(LPCTSTR lpszOldName, LPCTSTR lpszNewName);
	DECLDIR static void Remove(LPCTSTR lpszFileName);
	DECLDIR static BOOL GetStatus(LPCTSTR lpszFileName, CFileStatus& rStatus);
	static void SetStatus(LPCTSTR lpszFileName, const CFileStatus& status);

	//ULONGLONG SeekToEnd();
	//void SeekToBegin();

	DECLDIR ULONGLONG Seek(LONGLONG lOff, UINT nFrom);
	DECLDIR void SetLength(ULONGLONG dwNewLen);
	DECLDIR ULONGLONG GetLength() const;

	DECLDIR UINT Read(void* lpBuf, UINT nCount);
	DECLDIR void Write(const void* lpBuf, UINT nCount);

	//void Abort();
	DECLDIR void Flush();
	DECLDIR void Close();

	// Implementation
public:
	DECLDIR ~CFile();

	enum BufferCommand { bufferRead, bufferWrite, bufferCommit, bufferCheck };
	enum BufferFlags 
	{ 
		bufferDirect = 0x01,
		bufferBlocking = 0x02
	};
	//UINT GetBufferPtr(UINT nCommand, UINT nCount = 0,
	//	void** ppBufStart = NULL, void** ppBufMax = NULL);

protected:
	BOOL m_bCloseOnDelete;
	CString m_strFileName;
};